﻿using System;
using System.Collections.Generic;
using System.Reflection;
using FitNesseRunner.Model;

namespace FitNesseRunner
{
	internal class Reporter : IReporter, IDispatcherReporter
	{
		public void Pass(string message, params object[] args)
		{
			Console.ForegroundColor = ConsoleColor.Green;
			Console.WriteLine("[PASS]: " + message, args);
			Console.ResetColor();
		}

		public void Invoking(string className, string methodName, IEnumerable<string> parameterValues)
		{
			Console.WriteLine("Invoking {0}.{1}({2})", className, methodName, string.Join(", ", parameterValues));
		}

		public void InvocationFailed(string className, string methodName, IEnumerable<string> parameterValues, Exception exception)
		{
			Console.ForegroundColor = ConsoleColor.Yellow;
			Console.WriteLine("Failed to invoke {0}.{1}({2}).\nException:\n{3}", className, methodName, string.Join(" ", parameterValues), exception);
			Console.ResetColor();
		}

		public void Constructing(string className)
		{
			Console.WriteLine("constructing " + className);
		}

		public void Failed(object instance, string methodName, object expectedValue, object actualValue)
		{
			Console.ForegroundColor = ConsoleColor.Red;
			Console.WriteLine("[FAIL] {0}.{1}: expected='{2}', actual='{3}'", instance.GetType().Name, methodName,
							  expectedValue, actualValue);
			Console.ResetColor();
		}

		public void RunTest(string path)
		{
			Console.ForegroundColor = ConsoleColor.White;
			Console.WriteLine("Executing '{0}", path);
			Console.ResetColor();
		}

		public void FailedToConstruct(string className, Exception ex)
		{
			Console.ForegroundColor = ConsoleColor.Yellow;
			Console.WriteLine("Error creating an instance of {0}.\nException:\n{1}", className, ex);
			Console.ResetColor();
		}

		public void Invoking(PropertyInfo propertyInfo, string stringValue)
		{
			Console.WriteLine("Setting {0}.{1}={2}", propertyInfo.DeclaringType.Name, propertyInfo.Name, stringValue);
		}

		public void Show(string methodName, string result)
		{
			Console.ForegroundColor = ConsoleColor.Cyan;
			Console.WriteLine("Showing {0}: {1}", methodName, result);
			Console.ResetColor();
		}

		public void TestError(string message)
		{
			Console.ForegroundColor = ConsoleColor.DarkYellow;
			Console.WriteLine("Test error: " + message);
			Console.ResetColor();
		}

		public void InvocationError(string message, Type objectType, string query, IEnumerable<string> parameters)
		{
			Console.ForegroundColor = ConsoleColor.Yellow;
			Console.WriteLine("Invocation error: " + message);
			Console.ResetColor();
		}

		public void ReportException(Exception exception)
		{
			Console.WriteLine(exception);
		}
	}
}